// Copyright 2008 web2me.dev
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

package net.web2me.api.util;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

import org.apache.log4j.Logger;

import net.web2me.api.ParserException;


/**
 * Class that allows to add a file to the classpath dynamically
 * @author antony_miguel
 * @see http://forum.java.sun.com/thread.jspa?threadID=300557
 *
 */
public class ClassPathHacker {
	 
	private static Logger logger = Logger.getLogger(ClassPathHacker.class);
	private static final Class[] parameters = new Class[]{URL.class};
	 
	public static void addFile(String s) throws ParserException {
		File f = new File(s);
		addFile(f);
	}
	 
	public static void addFile(File f) throws ParserException {
		try {
			addURL(f.toURI().toURL());
		} catch (MalformedURLException e) {
			logger.error("MalformedURLException caught", e);
			throw new ParserException(e);
		}
	}
	 
	@SuppressWarnings("unchecked")
	public static void addURL(URL u) throws ParserException {
			
		URLClassLoader sysloader = (URLClassLoader)ClassLoader.getSystemClassLoader();
		Class sysclass = URLClassLoader.class;
	 
			Method method = null;
			try {
				method = sysclass.getDeclaredMethod("addURL",parameters);
			} catch (SecurityException e) {
				logger.error("SecurityException caught", e);
				throw new ParserException(e);
			} catch (NoSuchMethodException e) {
				logger.error("NoSuchMethodException caught", e);
				throw new ParserException(e);
			}
			
			method.setAccessible(true);
			
			try {
				method.invoke(sysloader,new Object[]{ u });
			} catch (IllegalArgumentException e) {
				logger.error("IllegalArgumentException caught", e);
				throw new ParserException(e);
			} catch (IllegalAccessException e) {
				logger.error("IllegalAccessException caught", e);
				throw new ParserException(e);
			} catch (InvocationTargetException e) {
				logger.error("InvocationTargetException caught", e);
				throw new ParserException(e);
			}
	}
	 
}